package generator

import (
	"fmt"

	"code/config"
	"code/handlers"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

// 写入文件 "generator/handlers/generatorHandler"
func WriteFile(filePath string, content string) error {
	return ioutil.WriteFile(filePath, []byte(content), 0644)
}

// 读取文件
func ReadFile(filePath string) (string, error) {
	data, err := ioutil.ReadFile(filePath)
	if err != nil {
		return "", err
	}
	return string(data), nil
}

// 检查文件是否存在
func checkFileExists(filePath string) bool {
	_, err := os.Stat(filePath)
	return !os.IsNotExist(err)
}

// 检查所有文件
func validateFiles(filePaths []string) {
	var allValid = true
	for _, path := range filePaths {
		if checkFileExists(path) {
			//fmt.Printf("文件存在: %s\n", path)
			//fmt.Println("\033[32m这是绿色文本\033[0m")
			fmt.Printf("\033[32m[✔️]文件存在: %s\033[0m\n", path)

		} else {
			//fmt.Printf("文件不存在: %s\n", path)
			fmt.Printf("\033[31m[x]文件不存在: %s\033[0m\n", path)

			allValid = false
		}
	}

	if !allValid {
		red.Println("存在未通过的文件检查，程序终止.")
		os.Exit(1) // 终止程序
	}
}

//移除指定区域的代码
func RemoveCodeBetweenTags(filePath string, config *config.Config) error {
	content, err := os.ReadFile(filePath)
	if err != nil {
		return err
	}

	lines := strings.Split(string(content), "\n")
	var newLines []string
	inTagSection := false

	for _, line := range lines {
		if strings.Contains(line, config.StartTag) {
			inTagSection = true
		}
		if strings.Contains(line, config.EndTag) {
			inTagSection = false
			continue // Skip the line with the end tag
		}
		if !inTagSection {
			newLines = append(newLines, line)
		}
	}

	// Write the new content back to the file
	err = os.WriteFile(filePath, []byte(strings.Join(newLines, "\n")), 0644)
	if err != nil {
		return err
	}

	fmt.Printf("%s 删除 %s_%s  代码。\n", filePath, config.Name, config.Tag)
	return nil
}

// 删除文件
func RemoveFile(filePath string) error {
	return os.Remove(filePath)
}

// InsertContentToFiles 在特定位置插入内容
func InsertContentToFiles(rootPath string, content string) error {
	err := filepath.Walk(rootPath, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		// 只处理文件
		if !info.IsDir() {
			fileContent, err := ioutil.ReadFile(path)
			if err != nil {
				return err
			}

			newContent := string(fileContent)
			lines := strings.Split(newContent, "\n")

			if strings.HasSuffix(path, ".xml") {
				// 在</mapper>前插入
				for i := len(lines) - 1; i >= 0; i-- {
					if strings.TrimSpace(lines[i]) == "</mapper>" {
						lines = append(lines[:i], append([]string{content}, lines[i:]...)...)
						break
					}
				}
			} else if strings.HasSuffix(path, ".java") {
				// 在最后一个}前插入
				for i := len(lines) - 1; i >= 0; i-- {
					if strings.TrimSpace(lines[i]) == "}" {
						lines = append(lines[:i], append([]string{content}, lines[i:]...)...)
						break
					}
				}
			} else {
				// 其他文件类型不处理
				return nil
			}

			// 写回文件
			err = ioutil.WriteFile(path, []byte(strings.Join(lines, "\n")), 0644)
			if err != nil {
				return err
			}

			blue.Printf("已在文件 %s 中插入内容\n", path)
		}

		return nil
	})

	return err
}

/**
 * 测试函数 插入数据看看
 */

func GenerateFilesTest(config config.Config) {
	filePath := config.ServiceFilePath
	content := fmt.Sprintf("//TAG_START:%s_%s_%s\n//<newElement>这是新插入的元素</newElement>\n//TAG_END:%s_%s_%s", config.Name, config.Tag, config.Type, config.Name, config.Tag, config.Type)

	err := InsertContentToFiles(filePath, content)
	if err != nil {
		fmt.Println("发生错误:", err)
	} else {
		fmt.Println("插入完毕:", filePath)
	}

	xmlPath := config.MapperXMLFilePath
	contentXml := fmt.Sprintf("<!-- TAG_START:%s_%s_%s -->\n<!-- 这是 XML 配置 -->\n<!-- TAG_END:%s_%s_%s -->", config.Name, config.Tag, config.Type, config.Name, config.Tag, config.Type)

	err2 := InsertContentToFiles(xmlPath, contentXml)
	if err2 != nil {
		fmt.Println("发生错误:", err2)
	} else {
		fmt.Println("插入完毕:", xmlPath)
	}
}

//最终插入文件
func finalInert(cfg config.Config, con config.CodeResult) {

	//插入控制器
	err := InsertContentToFiles(cfg.ControllerFilePath, con.ControllerCode)
	if err != nil {
		red.Printf("插入控制器发生错误:%s", err)
	} else {
		blue.Println("插入控制器完毕:", cfg.ControllerFilePath)
	}

	//插入服务
	err = InsertContentToFiles(cfg.ServiceFilePath, con.ServiceCode)
	if err != nil {
		red.Printf("插入服务发生错误:%s", err)
	} else {
		blue.Println("插入服务完毕:", cfg.ServiceFilePath)
	}

	//插入服务实现
	err = InsertContentToFiles(cfg.ServiceImplFilePath, con.ServiceImplCode)
	if err != nil {
		red.Printf("插入服务实现发生错误:%s", err)
	} else {
		blue.Println("插入服务实现完毕:", cfg.ServiceImplFilePath)
	}

	//插入mapper
	err = InsertContentToFiles(cfg.MapperFilePath, con.MapperCode)
	if err != nil {
		red.Printf("插入mapper发生错误:%s", err)
	} else {
		blue.Println("插入mapper完毕:", cfg.MapperFilePath)
	}

	//插入mapper xml
	err = InsertContentToFiles(cfg.MapperXMLFilePath, con.MapperXMLCode)
	if err != nil {
		red.Printf("插入mapper xml发生错误:%s", err)
	} else {
		blue.Println("插入mapper xml完毕:", cfg.MapperXMLFilePath)
	}

	green.Printf("%s 生成文件完毕", cfg.Action)

}

// 创建 API 接口文件相关
func GenerateInterFaceFiles(config config.Config) {
	green.Printf("创建 API 接口的相关文件逻辑\n")

	// type Code struct {
	// 	List    string
	// 	Add     string
	// 	Update  string
	// 	Del     string
	// 	Content string
	// }

	//var generatedCode Code

	// 根据 TypeArg 动态调用对应的生成函数
	switch config.Type {
	case "list":
		con := handlers.ListHandler(config)
		finalInert(config, con)
		//red.Printf("生成 %s 的代码\n", generatedCode.List)

	case "add":
		con := handlers.AddHandler(config)
		finalInert(config, con)
		//generatedCode.Add = strings.Join(handlers.AddHandler(Config, config), "\n")
	case "update":
		con := handlers.UpdateHandler(config)
		finalInert(config, con)
		//generatedCode.Update = strings.Join(UpdateBuild(config), "\n")
	case "del":
		con := handlers.DeleteHandler(config)
		finalInert(config, con)
		//generatedCode.Del = strings.Join(DelBuild(config), "\n")
	case "content":
		con := handlers.ContentHandler(config)
		finalInert(config, con)
		//generatedCode.Content = strings.Join(ContentBuild(config), "\n")
	default:
		red.Printf("错误: 未知的 TypeArg: %s\n", config.Type)
		return
	}

	// 这里可以添加后续的逻辑，比如将 generatedCode 处理为文件或打印输出
}

//创建dto 字段文件相关
func GenerateDtoFiles(config config.Config) {
	fmt.Println("创建DTO文件逻辑等后面处理:")
}

//根据tag 检测重复 有重复则列出 用红色字体标准
func CheckForDuplicateTag(filePath, tag string) bool {
	content, err := ReadFile(filePath)
	if err != nil {
		return false
	}

	// 检查是否包含重复的 TAG
	startTag := fmt.Sprintf("//TAG_START:%s", tag)
	endTag := fmt.Sprintf("//TAG_END:%s", tag)
	return strings.Contains(content, startTag) || strings.Contains(content, endTag)
}
